<template>
  <div>
    <common-table
      :saltId="$attrs.saltId"
      :clientHeight="clientHeight"
      :columns="columns"
      :tableData="tableData"
      @touchScroll="touchSearch"
      @cellClick="cellClick"
    ></common-table>
    <div v-show="!detailShow && !filtrateShow">
      <div id="conceal-container">
        <div class="to-top" @click="toTop">置顶</div>
        <div class="go-rpt-ls" @click="goRptLs">返回</div>
        <div class="filtrate" @click="filtrate" v-if="schemas.length > 0">
          筛选
        </div>
        <div class="open-detail" @click="openDetail">详情</div>
      </div>
      <div class="conceal-controller" @click="handleClick">
        {{ expandTimer ? "收起" : "展开" }}
      </div>

      <div class="paging-roundness">{{ tableData.length }}/{{ total }}</div>
    </div>

    <action-sheet v-model:show="filtrateShow" title="条件筛选">
      <div class="content">
        <van-form @submit="onSubmit">
          <van-cell-group inset>
            <template v-for="schema in schemas" :key="schema.field">
              <van-field
                v-if="schema.component == 'Input'"
                v-model="form[schema.field]"
                :name="schema.field"
                :label="schema.label"
                :placeholder="schema.placeholder"
              />
              <common-select
                v-else-if="schema.component == 'Select'"
                :label="schema.label"
                :placeholder="schema.placeholder"
                :componentProps="componentPropsIsFunc(schema?.componentProps)"
                v-model="form[schema.field]"
              ></common-select>
              <common-calendar
                v-else-if="schema.component == 'Calendar'"
                :label="schema.label"
                :componentProps="componentPropsIsFunc(schema?.componentProps)"
                :placeholder="schema.placeholder"
                v-model="form[schema.field]"
              ></common-calendar>
              <common-checkbox
                v-else-if="schema.component == 'Checkbox'"
                :label="schema.label"
                :placeholder="schema.placeholder"
                :componentProps="componentPropsIsFunc(schema?.componentProps)"
                v-model="form[schema.field]"
              ></common-checkbox>
            </template>
          </van-cell-group>
          <div
            style="margin: 16px; display: flex; justify-content: space-between"
          >
            <van-button round block type="default" @click="resetForm">
              重置
            </van-button>
            <van-button round block type="primary" native-type="submit">
              筛选
            </van-button>
          </div>
        </van-form>
      </div>
    </action-sheet>

    <action-sheet v-model:show="detailShow" title="报表详情">
      <div class="content">
        <van-cell-group>
          <template v-for="column in columns" :key="column.key">
            <van-cell :title="column.title" :value="convert(column)" />
          </template>
        </van-cell-group>
      </div>
    </action-sheet>
  </div>
</template>
  
<script>
import axios from "axios";
import dayjs from "dayjs";
import {
  Toast,
  ActionSheet,
  Cell as VanCell,
  CellGroup as VanCellGroup,
  Form as VanForm,
  Field as VanField,
  Button as VanButton,
} from "vant";
import { getQueryString,prexUrl } from "util/index.js";
import CommonTable from "@/components/common-table/index.vue";
import CommonSelect from "@/components/common-select/index.vue";
import CommonCheckbox from "@/components/common-checkbox/index.vue";
import CommonCalendar from "@/components/common-calendar/index.vue";

export default {
  name: "App",
  components: {
    CommonTable,
    CommonSelect,
    CommonCheckbox,
    CommonCalendar,
    ActionSheet,
    VanCell,
    VanCellGroup,
    VanForm,
    VanField,
    VanButton,
  },
  props: {
    schemas: {
      type: Array,
      default: () => {
        return [];
      },
    },
    fieldMapToTime: {
      type: Array,
      default: () => {
        return [];
      },
    },
    columns: {
      type: Array,
      default: () => {
        return [];
      },
    },
    tableData: {
      type: Array,
      default: () => {
        return [];
      },
    },
    apiUrl: {
      type: String,
      default: "",
    },
    getData: {
      type: Function,
      default: () => {
        return () => {};
      },
    },
  },
  data() {
    return {
      result: "",
      form: {},
      title: "首页",
      token: null,
      rowIndex: "",
      rowValue: {},
      detailShow: false,
      filtrateShow: false,
      params: {
        page: 1,
        size: 20,
      },
      total: 0,
      clientHeight: 0,
      initType: "",
      surroundings: "",
      element: null,
      expandTimer: null,
      collapseTimer: null,
      offsetHeight: 0,
      stepHeight: 0,
    };
  },
  mounted() {

    let _this = this;
    this.initType = "init";
    _this.clientHeight = document.documentElement.clientHeight;
    document.addEventListener("UniAppJSBridgeReady", function () {
      console.log("uni-app-plus 已准备好");
      uni.getEnv(function (res) {
        console.log("当前运行环境为：" + JSON.stringify(res));
        if (res.plus) {
          console.log("当前环境为【5+App】");
          _this.surroundings = "5+App";
        } else if (res.h5) {
          console.log("当前环境为h5");
          _this.surroundings = "h5";
        }
        if (getQueryString("token")) {
          _this.token = getQueryString("token");
          _this.getList();
        } else {
          Toast({
            duration: 500,
            message: "用户认证失效~",
          });
        }
      });
    });
    console.log("token", _this.token);

    this.element = document.getElementById("conceal-container");
    this.element.style.height = null;
    // display 设为 null，要将元素隐藏
    this.element.style.display = "none";
  },
  methods: {
     isFunction(variable) {
      return typeof variable === "function";
    },
    componentPropsIsFunc(componentProps){
      if(!componentProps){
        return {}
      }
      if(this.isFunction(componentProps)){
         return componentProps({form:this.form})
      }else{
         return componentProps
      }
    },
    convert(column) {
      if (column.slots) {
        return column?.slots?.default({ row: this.rowValue });
      } else {
        return this.rowValue[column.key] || '---';
      }
    },
    goRptLs() {
      if (this.surroundings == "5+App") {
      } else {
        window.location.href =  prexUrl()+"/longnows#/rpt-ct" + "?token=" + this.token;
      }
    },
    openDetail() {
      if (this.rowIndex === "") {
        Toast({
          duration: 1500,
          message: "请单击选中一行~",
        });
        return false;
      }
      this.detailShow = true;
    },
    getList() {
      console.log("initData........", this.token);
      let _this = this;
      // 自定义加载图标

      Toast.loading({
        duration: 0,
        message: "加载中...",
        forbidClick: true,
        loadingType: "spinner",
      });

      let searchForm = {};
      Object.keys(_this.form).forEach((key) => {
        if (_this.form[key]) {
          searchForm[key] = _this.form[key];
        }
      });
      let fieldKeys = this.fieldMapToTime.map((item) => {
        if (item && item[0]) {
          let key = item[0];
          let startKey = item[1] && item[1][0];
          let endKey = item[1] && item[1][1];
          let format = item[2] || "YYYY-MM-DD";
          let native=item[3]
          let value = _this.form[key];
          if (startKey && endKey && value && value.length == 2) {
            searchForm[startKey] = value[0] && dayjs(value[0]).hour(0).minute(0).second(0).format(format);
            searchForm[endKey] = value[1] && dayjs(value[1]).hour(23).minute(59).second(59).format(format);
            if(native){
              //生成原始时间戳格式
              searchForm[startKey]=(new Date(searchForm[startKey])).valueOf()
              searchForm[endKey]=(new Date(searchForm[endKey])).valueOf()
            }
            delete searchForm[key];
          }
        }
      });
      axios({
        method: "post",
        headers: {
          Authorization: "Bearer " + this.token,
        },
        params: _this.params,
        data: searchForm,
        url: this.apiUrl || "/scm/api/v1/no",
      })
        .then((response) => {
          if (response.data.code === 0) {
            _this.total = response.data.total;
            _this.getData(response?.data?.data || [], _this.initType);
            _this.initType = "done";
            Toast.clear();
          } else {
            _this.params = {
              page: 1,
              size: 20,
            };
            _this.total = 0;
            _this.toTop();
            _this.initType === "init";
            _this.getData([], _this.initType);
            Toast({
              duration: 1500,
              message: response.data.message,
            });
          }
        })
        .catch((response) => {
          Toast.clear();
          if (_this.surroundings == "5+App") {
            Toast({
              duration: 500,
              message: "用户认证失效~",
            });
            // 在uniapp中运行
            console.log("在uniapp中运行");
            uni.postMessage({
              data: {
                action: "navigateTo",
                id: "1001",
              },
            });
          } else {
            // 不在uniapp中运行
            Toast({
              duration: 1500,
              message: "用户认证失效~",
            });
            window.location.href =  prexUrl()+"/longnows#/login";

            console.log("不在uniapp中运行");
          }
        });
    },
    touchSearch() {
      if (this.initType === "init") {
        return false;
      }
      console.log("touchSearch........");
      if (this.total > 0 && this.params.page < this.total / this.params.size) {
        console.log(this.params.page);
        this.params.page++;
        this.getList();
      } else {
        Toast({
          duration: 500,
          message: "没有更多数据了~",
        });
      }
    },
    toTop() {
      document
        .getElementsByClassName("vxeMainTable")[0]
        ?.querySelector(".vxe-table--body-wrapper")
        .scrollTo(0, 0);
    },
    cellClick({ row, column, rowIndex, columnIndex }) {
      this.rowIndex = rowIndex;
      row["seq"] = rowIndex + 1;
      this.rowValue = row;
    },
    filtrate() {
      this.filtrateShow = true;
    },
    onSubmit() {
      console.log(this.form);
      this.toTop();
      this.params = {
        page: 1,
        size: 20,
      };
      this.initType = "init";
      this.getList();
    },
    resetForm() {
      this.form = {};
    },
    handleClick() {
      // 如果当前 expandTimer 值存在，就标识当前是正在展开或已经展开，接下来要进行的是收起操作
      if (this.expandTimer) {
        clearInterval(this.expandTimer);
        this.expandTimer = null;
        // 收起时的初始高度是元素的当前实际高度，即使是元素在展开动画过程中，也要从当前元素高度进行收起动画
        let height = this.element.offsetHeight;

        this.collapseTimer = setInterval(() => {
          height -= this.stepHeight;
          if (height <= 0) {
            // 高度小于等于 0 代表动画完成，将数据进行重置
            clearInterval(this.collapseTimer);
            this.offsetHeight = 0;
            // 要将元素的高度置为 null，不然会影响下一次展开时获取正确的高度
            this.element.style.height = null;
            // display 设为 null，要将元素隐藏
            this.element.style.display = "none";
            return;
          }
          this.element.style.height = height + "px";
        }, 10);
      } else {
        clearInterval(this.collapseTimer);
        this.collapseTimer = null;
        // 获取元素总高度
        this.element.style.display = "block";
        let height = 0;
        // 如果当前没有 offsetHeight 就要重新获取
        if (!this.offsetHeight) {
          this.offsetHeight = this.element.offsetHeight;
          // 每一次给元素添加或减少的高度，除以 30 是自己设定的，跟下面定时器的每次间隔时间一起控制整个高度动画的时长，也可以给函数添加第二个时间参数，可以自由控制动画时间
          this.stepHeight = this.offsetHeight / 30;
        } else {
          // 如果有 offsetHeight 就代表正在进行收起动画，应该从收起动画的当前高度进行展开动画
          height = this.element.offsetHeight;
        }

        this.element.style.height = height + "px";

        this.expandTimer = setInterval(() => {
          height += this.stepHeight;
          if (height >= this.offsetHeight) {
            // 当前高度如果已经到了元素的实际高度，就要清除定时器
            clearInterval(this.expandTimer);
            // 将 expandTimer 设为 1 是因为当前是以 expandTimer 判断是否正在或已经进行了展开动画，所以要在完成是设为 1，在收起动画的开始时会将值设为 null
            this.expandTimer = 1;
            this.element.style = null;
            return;
          }
          this.element.style.height = height + "px";
        }, 10);
      }
    },
  },
};
</script>
  
  <style>
.wrapper {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
}
.filtrate {
  width: 50px;
  height: 50px;
  border-radius: 25px;
  background: #6913a6;
  color: #ffffff;
  box-shadow: 0px 1px 8px 0px rgba(0, 0, 0, 0.08);
  text-align: center;
  line-height: 50px;
  font-size: 13px;
  opacity: 0.9;
  margin-bottom: 15px;
}
.open-detail {
  width: 50px;
  height: 50px;
  border-radius: 25px;
  background: #46a613;
  color: #ffffff;
  box-shadow: 0px 1px 8px 0px rgba(0, 0, 0, 0.08);
  text-align: center;
  line-height: 50px;
  font-size: 13px;
  opacity: 0.9;
}
.go-rpt-ls {
  width: 50px;
  height: 50px;
  border-radius: 25px;
  background: #266fe8;
  color: #ffffff;
  box-shadow: 0px 1px 8px 0px rgba(0, 0, 0, 0.08);
  text-align: center;
  line-height: 50px;
  font-size: 13px;
  opacity: 0.9;
  margin-bottom: 15px;
}
#conceal-container {
  display: grid;
  /* grid-template-rows: 0fr; */
  overflow: hidden;
  transition: all 0.1s;
  position: fixed;
  z-index: 999999;
  right: 20px;
  bottom: 140px;
  box-shadow: 0px 1px 8px 0px rgba(0, 0, 0, 0.08);
  text-align: center;
  line-height: 50px;
  font-size: 13px;
  opacity: 0.9;
}
.conceal-controller {
  position: fixed;
  z-index: 999999;
  right: 20px;
  bottom: 80px;
  width: 50px;
  height: 50px;
  border-radius: 25px;
  background: #1a13a6;
  color: #ffffff;
  box-shadow: 0px 1px 8px 0px rgba(0, 0, 0, 0.08);
  text-align: center;
  line-height: 50px;
  font-size: 13px;
  opacity: 0.9;
}
.to-top {
  width: 50px;
  height: 50px;
  border-radius: 25px;
  background: #ff9e40;
  color: #ffffff;
  box-shadow: 0px 1px 8px 0px rgba(0, 0, 0, 0.08);
  text-align: center;
  line-height: 50px;
  font-size: 13px;
  opacity: 0.9;
  margin-bottom: 15px;
}
.paging-roundness {
  position: fixed;
  z-index: 999999;
  right: 20px;
  bottom: 20px;
  width: 50px;
  height: 50px;
  border-radius: 25px;
  background: #d34f18;
  color: #ffffff;
  box-shadow: 0px 1px 8px 0px rgba(0, 0, 0, 0.08);
  text-align: center;
  line-height: 50px;
  font-size: 13px;
  opacity: 0.9;
}
</style>
  